package com.example.demo.剑指offer;

/**
 * @author：zzc
 * @date: 2022/8/18
 */
public class 表示数值的字符串 {

    //请实现一个函数用来判断字符串是否表示数值（包括整数和小数）。
    //
    //数值（按顺序）可以分成以下几个部分：
    //
    //若干空格
    //一个 小数 或者 整数
    //（可选）一个 'e' 或 'E' ，后面跟着一个 整数
    //若干空格
    //小数（按顺序）可以分成以下几个部分：
    //
    //（可选）一个符号字符（'+' 或 '-'）
    //下述格式之一：
    //至少一位数字，后面跟着一个点 '.'
    //至少一位数字，后面跟着一个点 '.' ，后面再跟着至少一位数字
    //一个点 '.' ，后面跟着至少一位数字
    //整数（按顺序）可以分成以下几个部分：
    //
    //（可选）一个符号字符（'+' 或 '-'）
    //至少一位数字
    //部分数值列举如下：
    //
    //["+100", "5e2", "-123", "3.1416", "-1E-16", "0123"]
    //部分非数值列举如下：
    //
    //["12e", "1a3.14", "1.2.3", "+-5", "12e+5.4"]
    //
    //
    //示例 1：
    //
    //输入：s = "0"
    //输出：true
    //示例 2：
    //
    //输入：s = "e"
    //输出：false
    //示例 3：
    //
    //输入：s = "."
    //输出：false
    //示例 4：
    //
    //输入：s = "    .1  "
    //输出：true
    //
    //
    //提示：
    //
    //1 <= s.length <= 20
    //s 仅含英文字母（大写和小写），数字（0-9），加号 '+' ，减号 '-' ，空格 ' ' 或者点 '.' 。

    //遍历字符串：
    //
    //出现 +/- 时，位置必须是在第 0 位，或者 e/E 的后面一位
    //出现 . 时，在此之前不能出现 . 或者 e/E
    //出现 e/E 时，前面不能出现 e/E，并且必须出现过数字、

    class Solution {

        public boolean isNumber(String s) {
            if (s == null || s.trim().length() == 0) {
                return false;
            }
            char[] chars = s.trim().toCharArray();
            boolean findNum = false;
            boolean findE = false;
            boolean findDot = false;
            for (int i = 0, n = chars.length; i < n; ++i) {
                if (chars[i] == '+' || chars[i] == '-') {
                    if (i != 0 && chars[i - 1] != 'e' && chars[i - 1] != 'E') {
                        return false;
                    }
                } else if (chars[i] >= '0' && chars[i] <= '9') {
                    findNum = true;
                } else if (chars[i] == '.') {
                    if (findDot || findE) {
                        return false;
                    }
                    findDot = true;
                } else if (chars[i] == 'e' || chars[i] == 'E') {
                    if (findE || !findNum) {
                        return false;
                    }
                    findE = true;
                    findNum = false; // 确保e之后也出现数
                } else {
                    return false;
                }
            }
            return findNum;
        }
    }

}
